#pragma once

#include "ZNetworkController.h"
#include "ZIocpProcessThread.h"
#include "ZIocp.h"
#include "ZCommon.h"

namespace	Z	{

//------------------------------------------------------------------------------------------------------------------------
class	_ZNetworkApi	SocketNetworkController
	:	public NetworkController,
		public IocpProcessThread
{
public:
	enum	{	create	= destroy + 1,	close,	initialNetworkId	};
public:
	SocketNetworkController(size_t numPooledThread);
	virtual	~SocketNetworkController();
	BOOL	postCompletionStatus(ULONG_PTR completionKey, DWORD bytesTransferred = 0, OVERLAPPED* pOverlapped = nullptr);
	
protected:
	virtual	bool	start(MessageReceiver* pMessageReceiver);
	virtual	void	cleanup();
	virtual	bool	onCreate(AsyncSocket* pSocket);
	virtual	bool	onClose(NetworkId kNetworkId, bool graceful, bool notify);
	virtual	bool	onIoComplete(NetworkId kNetworkId, size_t bytesTransferred, OVERLAPPED* pOverlapped);
	virtual	void	send(Stream* pStream, NetworkId kNetworkId);
private:
	virtual	void	processingThread();
	bool	onClose(AsyncSocket* pSocket, bool graceful, bool notify);
	virtual	AsyncSocket*	getSocket(NetworkId kNetworkId)	const	= 0;

protected:
	mutable	rwmutex_t	mSocketLock;
private:
	Iocp	mIocp;
	const	size_t	mNumPooledThread;
	void	onRegisterSocket(AsyncSocket* pSocket);
};

}